`timescale 1ns / 1ps
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Company:			Microsystems Design Lab (MDL)
//					The Pennsylvania State University
// Engineer: 		Yang Xiao
//
// Create Date:		6/13/2012
// Design Name: 	Fast Hessian Accelerator
// Module Name:     integral_image_buffer
// Project Name:	Future Store Analytics
// Target Devices: 	
// Tool versions:
// Description:		This module provides a buffer to the integral image.
//					The module instantiates N instances of integral_image_row (i.e. dual port BRAM). N is number of 
//					rows.
//
// Dependencies:
//
// Revision:
// Revision 1.0 - File Created
//
// Additional Comments:
//
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

module integral_image_buffer
(
	//----------------------------
	// Input ports
	//----------------------------
	clk			,	
	addra		,		// --- address port A ---
	wea			,		// --- write enable port A ---
	dina		,		// --- data port A ---	
	addrb		,		// --- address port B ---
	web			,  		// --- write enable port B ---
	dinb		, 		// --- data port B ---
	
	//----------------------------
	// Output ports
	//----------------------------
	douta		,
	doutb
);

	//--------------------------
	// Parameters
	//--------------------------
	parameter PXL_WIDTH			= 32;
	parameter NUM_ROWS			= 256;
	parameter NUM_COLS			= 1024;
	parameter ADDR_WIDTH		=	(NUM_COLS <= 2)    ? 1  :
									(NUM_COLS <= 4)    ? 2  :
									(NUM_COLS <= 8)    ? 3  :
									(NUM_COLS <= 16)   ? 4  :
									(NUM_COLS <= 32)   ? 5  :
									(NUM_COLS <= 64)   ? 6  :
									(NUM_COLS <= 128)  ? 7  :
									(NUM_COLS <= 256)  ? 8  :
									(NUM_COLS <= 512)  ? 9  :
									(NUM_COLS <= 1024) ? 10 :
									(NUM_COLS <= 2048) ? 11 :
									(NUM_COLS <= 4096) ? 12 :
									(NUM_COLS <= 8192) ? 13 : 14;
	
	//--------------------------
	// Input Ports
	//--------------------------
	input 										clk		;	
	input [ADDR_WIDTH*NUM_ROWS-1:0]				addra	;
	input [NUM_ROWS-1:0]						wea		;
	input [PXL_WIDTH*NUM_ROWS-1:0]				dina	;	
	input [ADDR_WIDTH*NUM_ROWS-1:0]				addrb	;
	input [NUM_ROWS-1:0]						web		;
	input [PXL_WIDTH*NUM_ROWS-1:0]				dinb	;
	
	//--------------------------
	// Output Ports
	//--------------------------
	output [PXL_WIDTH*NUM_ROWS-1:0]				douta	;
	output [PXL_WIDTH*NUM_ROWS-1:0]				doutb	;

	///////////////////////////////////////////////////////////////////
	// Begin Design
	///////////////////////////////////////////////////////////////////
	//-------------------------------------------------
	// Signal Declarations: local params
	//-------------------------------------------------
	// None
	
	//-------------------------------------------------
	// Signal Declarations: reg
	//-------------------------------------------------
	// None
	
	//-------------------------------------------------
	// Signal Declarations: wire
	//-------------------------------------------------
	// None	

	//---------------------------------------------------------------
	// Assignments
	//---------------------------------------------------------------
	// None
	
	//---------------------------------------------------------------
	// Instantiations
	//---------------------------------------------------------------
	generate
		genvar i;		
		for (i = 0; i < NUM_ROWS; i = i + 1) begin : II_ROW
			dp_bram	#(
				.WIDTH(PXL_WIDTH)	,
				.N_DEPTH(NUM_COLS)	,
				.W_DEPTH(ADDR_WIDTH)
			) 
			dp_bram_inst (
				.clka(clk)											,				
				.dina(dina[((i+1)*PXL_WIDTH)-1:i*PXL_WIDTH])		,
				.addra(addra[((i+1)*ADDR_WIDTH)-1:i*ADDR_WIDTH])	,
				.wea(wea[i])										,
				.douta(douta[((i+1)*PXL_WIDTH)-1:i*PXL_WIDTH])		,
					
				.clkb(clk)											,
				.dinb(dinb[((i+1)*PXL_WIDTH)-1:i*PXL_WIDTH])		,
				.addrb(addrb[((i+1)*ADDR_WIDTH)-1:i*ADDR_WIDTH])	,
				.web(web[i])										,
				.doutb(doutb[((i+1)*PXL_WIDTH)-1:i*PXL_WIDTH])
			);
		end
	endgenerate

	//---------------------------------------------------------------
	// Combinatorial Logic
	//---------------------------------------------------------------
	// None

	//---------------------------------------------------------------
	// Sequential Logic
	//---------------------------------------------------------------
	// None

endmodule
